home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
asm_kit
/
circle.asm
< prev
next >
Wrap
Assembly Source File
|
1985-11-06
|
5KB
|
184 lines
TITLE 'Fast Circle Plot'
BIOSCALL MACRO
INT 10H ;BIOS service id in AH
ENDM
STACK SEGMENT PARA STACK 'STACK'
DB 64 DUP('STACK ')
STACK ENDS
CODE SEGMENT BYTE PUBLIC
;-------------------------------------------
;PROCEDURE CIRCLE(X,Y,RADIUS,NUMER,DENOM,
; COLOR:INTEGER)
;
;Dan Lee July 1,1982
;SourceWare
;
;draws a circle at center (x,y) with aspect
;ratio numer/denom; radius in column units
;
;assumes entry via inter-segment call
;
;FRAME VALUE X : BP+16 BP+14
; VALUE Y : BP+14 BP+12
; VALUE RADIUS : BP+12 BP+10
; VALUE NUMER : BP+10 BP+8
; VALUE DENOM : BP+8 BP+6
; VALUE COLOR : BP+6 BP+4
;-------------------------------------------
ASSUME CS:CODE,SS:STACK
PUBLIC CIRCLE
CIRCLE PROC NEAR
PUSH BP ;caller's frame pntr
MOV BP,SP ;set proc frame pntr
MOV AX,[BP+8] ;get aspect numer and
MOV BX,1000 ;scale it by 1000
IMUL BX
MOV CX,[BP+6] ;get aspect denom
IDIV CX ;AX=aspect*1000
PUSH AX ;store aspect*1000
XCHG AX,CX ;get denom in AX
MOV CX,[BP+8] ;get numer in CX
IMUL BX ;AX=denom*1000
IDIV CX ;AX=inv aspect*1000
MOV [BP+6],AX ;store it
POP AX ;get aspect*1000
MOV [BP+8],AX ;and store it
;
; start by incrementing Y by one unit and
; decrementing X by TAN units*inv aspect
; start at (RADIUS,Y) and plot to 45 deg
;
MOV AX,[BP+10] ;get radius for
MOV BX,1000 ;initial X and scale
IMUL BX ;up by 1000
XOR DI,DI ;zero initial Y value
CR5: PUSH AX ;save lo word X*1000
PUSH DX ;save hi word X*1000
XOR DI,DI ;begin round process
ADD AX,500 ;'one-half'
ADC DX,BX
MOV BX,1000 ;rescale X by 1000
IDIV BX ;to graph
MOV BX,AX ;BX=1st quad X
ADD AX,[BP+14] ;add X origin
MOV DX,[BP+12] ;get Y origin
SUB DX,DI ;and sub Y to plot
MOV CX,AX ;get X to plot
MOV AL,[BP+4] ;get color
MOV AH,12 ;write dot funct select
PUSH AX ;save write do parms
BIOSCALL ;write 1st quad point
POP AX ;resore write dot parms
SUB CX,BX ;get 2nd quad
SUB CX,BX ;X+origin
PUSH AX ;save write dot parms
BIOSCALL ;write 2nd quad point
POP AX ;restore write dot parms
ADD DX,DI ;get 3rd quad
ADD DX,DI ;Y+origin
PUSH AX ;save write dot parms
BIOSCALL ;plot 3rd quad point
POP AX ;restore write dot parms
ADD CX,BX ;get 4th quad
ADD CX,BX ;X+origin
BIOSCALL ;plot 4th quad point
XCHG CX,BX ;get 1st quad X
INC DI ;get new Y
MOV AX,DI ;AX=Y
MOV BX,[BP+6] ;BX=inv aspect*1000
IMUL BX ;AX=Y*inv aspect*1000
IDIV CX ;AX=TAN*inv aspect*1000
XOR DX,DX ;zero remainder
MOV SI,AX ;SI=TAN*inv aspect*1000
IDIV BX ;AX =TAN
CMP AX,1 ;TAN=1?
POP DX ;DX=hi word X*1000
POP AX ;AX=lo word X*1000
JAE CR7 ;yes, go to next sector
NEG SI ;to decrement *X
MOV BX,-1 ;negative carry
ADD AX,SI ;new X value
ADD DX,BX ;hi word carry
JMP SHORT CR5 ;plot new point
;
; plot 45 to 90 degrees
; now decrease X by one unit and
; increase Y by COT units*aspect ratio
;
CR7: MOV AX,DI ;get next Y to plot and
MOV BX,1000 ;scale by 1000
IMUL BX ;DX:AX=Y*1000
MOV DI,CX ;DI=last X value
DEC DI ;next x to plot
CR8: PUSH AX ;save lo word y*1000
PUSH DX ;save hi word y*1000
XOR BX,BX ;begin round process
ADD AX,500 ;'one-half'
ADC DX,BX
MOV BX,1000 ;rescale Y to plot
IDIV BX ;AX=Y
MOV BX,AX ;BX=1st quad Y coord
ADD AX,[BP+12] ;add Y origin
MOV CX,[BP+14] ;CX=X origin
ADD CX,DI ;X to plot
MOV DX,AX ;Y to plot
MOV AL,[BP+4] ;get color
MOV AH,12 ;write dot funct select
PUSH AX ;save write dot parms
BIOSCALL ;write 1st quad point
POP AX ;restore write dot parms
SUB CX,DI ;get 2nd quad
SUB CX,DI ;X to plot
PUSH AX ;save write dot parms
BIOSCALL ;plot 2nd quad point
POP AX ;restore write dot parms
SUB DX,BX ;get 3rd quad
SUB DX,BX ;Y to plot
PUSH AX ;save write dot parms
BIOSCALL ;write 3rd quad point
POP AX ;restore write dot parms
ADD CX,DI ;get 4th quad
ADD CX,DI ;X to plot
BIOSCALL ;plot 4th quad point
SUB DX,[BP+12] ;DX=Y=Y origin
NEG DX ;Y origin adjust
XCHG CX,DX ;CX=Y
OR DI,DI ;90 deg?
JS CR11 ;yes, exit
DEC DI ;get new X
MOV AX,DI ;AX=X
MOV BX,[BP+8] ;BX=aspect*1000
IMUL BX ;AX=aspect*1000*X
IDIV CX ;AX=aspect*1000*COT
MOV SI,AX ;SI=change in Y
POP DX ;DX=hi word Y*1000
POP AX ;AX=lo word Y*1000
XOR BX,BX
OR SI,SI ;for sign check
JNS CR10 ;posiI=change in Y
POP DX ;DX=hi word Y*1000
POP AX ;AX=lo word Y*1000
XOR BX,BX
OR SI,SI ;for sign check
JNS CR10 ;positive
MOV BX,-1 ;negative carry
CR10: ADD AX,SI ;AX=new X value
ADC DX,BX ;hi word carry
JMP SHORT CR8 ;plot next point
;
; exit
;
CR11: ADD SP,4 ;adjust stackp pntr
POP BP ;caller's frame pntr
RET 12 ;release parms
CIRCLE ENDP
CODE ENDS
END END